#include "Vis2DRenderer.hpp"

namespace zzz{
zzz::Vis2DRenderer::Vis2DRenderer()
{
  posx_=0;posy_=0;
  zoomratio_=1;
  showMsg_=false;
  allowmove_=true;
  allowzoom_=true;
  middleButton_ = false;
}


void Vis2DRenderer::OnMouseMove(unsigned int nFlags,int x,int y)
{
  if(allowmove_ && middleButton_)
  {
    posx_+=x-lastx_;
    posy_-=y-lasty_;
    lastx_=x;
    lasty_=y;
    Redraw();
  }
}

void Vis2DRenderer::OnMButtonDown(unsigned int nFlags,int x,int y)
{
  middleButton_=true;
  lastx_=x;
  lasty_=y;
}

void Vis2DRenderer::OnMButtonUp(unsigned int nFlags,int x,int y)
{
  middleButton_=false;
  if (middletimer_.Elapsed()<0.3)
  {
    zoomratio_=1;
    posx_=0;
    posy_=0;
    Redraw();
  }
  middletimer_.Restart();
}

bool Vis2DRenderer::InitState()
{
  Renderer::InitState();
  glDisable(GL_DEPTH_TEST);
  return true;

}

void Vis2DRenderer::SetCenter(int width,int height)
{
  posx_=(width_-width)/2;
  posy_=(height_-height)/2;
}

void Vis2DRenderer::OnMouseWheel(unsigned int nFlags, int zDelta, int x,int y)
{
  if (!allowzoom_) return;
  double newratio;
  if (zDelta>0) newratio=zoomratio_*1.1;
  else newratio=zoomratio_/1.1;
  posx_=x-(x-posx_)*newratio/zoomratio_;
  posy_=height_-y-(height_-y-posy_)*newratio/zoomratio_;
  zoomratio_=newratio;
  Redraw();
}

void Vis2DRenderer::SetRasterPosRelative(double x, double y) const
{
  SetRasterPos(posx_+x*zoomratio_, posy_+y*zoomratio_);
}

Vector3d Vis2DRenderer::UnProjectRelative(double winx,double winy) const
{
  return UnProject(posx_+winx*zoomratio_, posy_+winy*zoomratio_, 0);
}

Vector2d Vis2DRenderer::GetHoverPixel(int mouse_x, int mouse_y, int img_x, int img_y) const
{
  double glx=mouse_x,gly=height_-mouse_y;  //to opengl coordinate
  glx-=posx_+img_x;gly-=posy_+img_y;  //to image coordinate
  glx/=zoomratio_;gly/=zoomratio_;  //unzoom
  return Vector2d(gly,glx);  //to row,column coordinate
}

void Vis2DRenderer::DrawObj()
{
  return;
}

void Vis2DRenderer::Draw2DPoint(double x, double y, const Colorf& color, float size)
{
  color.ApplyGL();
  GLPointSize::Set(size);
  Vector3d p=UnProjectRelative(x,y);
  glBegin(GL_POINTS);
  glVertex3dv(p.Data());
  glEnd();
  GLPointSize::Restore();
}

void Vis2DRenderer::Draw2DLine(double x0, double y0, double x1, double y1, const zzz::Colorf& color, float size)
{
  color.ApplyGL();
  GLLineWidth::Set(size);
  Vector3d p0=UnProjectRelative(x0,y0);
  Vector3d p1=UnProjectRelative(x1,y1);
  glBegin(GL_LINES);
  glVertex3dv(p0.Data());
  glVertex3dv(p1.Data());
  glEnd();
  GLLineWidth::Restore();
}

void Vis2DRenderer::SetupCamera()
{
  Renderer::SetupCamera();
  glPixelZoom(zoomratio_,zoomratio_);
  glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  SetRasterPos(posx_, posy_);
}

}
